class MyPromise {
    constructor(executor) {
        /* 准备回调队列 */

        // 成功回调队列
        this.thens = [];

        // 错误回调队列
        this.catches = [];

        // 终点回调队列
        this.finallyFns = [];

        /* 绑定任务函数中的resolve与reject */
        this.executor = executor.bind(
            this, //当前promise实例
            MyPromise.doResolve.bind(this), //当前promise实例执行resolve时,this不变
            MyPromise.doReject.bind(this) //当前promise实例执行reject时,this不变
        );

        /* 稍后执行任务函数 执行权先让给后续的then,catch,finally */
        setTimeout(() => {
            this.executor();
        });
    }

    /* promise实例执行resolve */
    static doResolve(data) {
        const nextThenCallback = this.thens.shift();
        if (nextThenCallback) {
            try {
                data = nextThenCallback(data);

                // 如果不是Promise对象 继续调用下一个then
                if (!(data instanceof MyPromise)) {
                    MyPromise.doResolve.call(this, data);
                } else {
                    // 如果是Promise对象 继续调用下一个then
                    // MyPromise.switchThis(data, [
                    //     ...this.thens,
                    //     ...this.catches,
                    //     this.finallyFns,
                    // ]);
                    data.thens = MyPromise.switchThis(data, this.thens);
                    data.catches = MyPromise.switchThis(data, this.catches);
                    data.finallyFns = MyPromise.switchThis(
                        data,
                        this.finallyFns
                    );
                }
            } catch (err) {
                MyPromise.doReject.call(this, err);
            }
        } else {
            this.finallyFns[0] && this.finallyFns[0]();
        }
    }

    /* promise实例执行reject */
    static doReject(err) {
        const nextCatchCallback = this.catches.shift();
        if (nextCatchCallback) {
            nextCatchCallback(err);
        }
        this.finallyFns[0] && this.finallyFns[0]();
    }

    /* 语法糖：创建一个立即resolve的Promise对象 */
    static resolve(data) {
        return new MyPromise((resolve) => resolve(data));
    }

    /* 语法糖：创建一个立即reject的Promise对象 */
    static reject(err) {
        return new MyPromise((resolve, reject) => reject(err));
    }

    /* 将一个回调队列中的所有回调重新绑定this */
    static switchThis(thisArg, cbArr) {
        cbArr.forEach((cb) => {
            // console.log("cb=",cb);
            cb = cb.bind(thisArg);
        });
        return cbArr;
    }

    /* 收集成功回调到队列 */
    then(onData) {
        this.thens.push(onData);
        return this;
    }

    /* 收集失败回调到队列 */
    catch(onErr) {
        this.catches.push(onErr);
        return this;
    }

    /* 收集终点回调到队列（此处假设只有一个终点回调） */
    finally(onFinish) {
        this.finallyFns[0] = onFinish;
        return this;
    }

}

module.exports = MyPromise;
